package com.knowledge.common.utils;

import com.knowledge.common.exception.BusinessException;
import net.dankito.readability4j.Article;
import net.dankito.readability4j.Readability4J;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * HTML 文件处理工具类
 * 拉取网页 → 清理 HTML → 保存为临时文件 → 返回路径
 */
@Component
public class HtmlFileUtil {

    private static final Logger log = LoggerFactory.getLogger(HtmlFileUtil.class);
    private static final int TIMEOUT = 30000; // 30秒超时
    private static final String USER_AGENT = "Mozilla/5.0 (compatible; AISHEART-DocParser/1.0)";

    /**
     * 从 URL 拉取网页、清理并保存为临时文件
     *
     * @param url 网页 URL
     * @return 清理后的 HTML 临时文件路径
     * @throws BusinessException 处理失败时抛出
     */
    public Path fetchAndSaveToTempFile(String url) {
        try {
            log.info("开始从 URL 拉取网页: {}", url);

            // 1. 验证 URL
            validateUrl(url);

            // 2. 拉取网页
            Document doc = Jsoup.connect(url)
                    .userAgent(USER_AGENT)
                    .timeout(TIMEOUT)
                    .followRedirects(true)
                    .get();
            String html = doc.html();
            log.info("成功拉取网页,内容长度: {}", html.length());

            // 3. 使用 Readability4j 清理 HTML
            String cleanHtml = cleanHtml(html, url);
            log.info("HTML 清理完成,清理前: {} 字符,清理后: {} 字符", html.length(), cleanHtml.length());

            // 4. 保存到临时文件
            Path tempFile = Files.createTempFile("web-", ".html");
            Files.writeString(tempFile, cleanHtml);
            log.info("HTML 文件已保存到: {}", tempFile);

            return tempFile;

        } catch (IOException e) {
            log.error("从 URL 拉取失败: {}", url, e);
            throw new BusinessException("从 URL 拉取失败: " + e.getMessage(), e);
        } catch (Exception e) {
            log.error("处理 HTML 失败: {}", url, e);
            throw new BusinessException("处理 HTML 失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除临时文件
     *
     * @param filePath 文件路径
     */
    public void deleteFile(Path filePath) {
        try {
            if (filePath != null && Files.exists(filePath)) {
                Files.delete(filePath);
                log.debug("临时文件已删除: {}", filePath);
            }
        } catch (IOException e) {
            log.warn("删除临时文件失败: {}", filePath, e);
        }
    }

    /**
     * 使用 Readability4j 清理 HTML（去除广告、导航等无关内容）
     */
    private String cleanHtml(String html, String url) {
        try {
            Readability4J readability = new Readability4J(url, html);
            Article article = readability.parse();
            String content = article.getContent();

            if (content != null && !content.trim().isEmpty()) {
                log.debug("Readability4j 成功提取主要内容");
                return content;
            }
        } catch (Exception e) {
            log.warn("Readability4j 提取失败,使用原始 HTML: {}", e.getMessage());
        }

        // 如果 Readability4j 失败,返回原始 HTML
        return html;
    }

    /**
     * 验证 URL 格式和安全性
     */
    private void validateUrl(String url) {
        if (url == null || url.trim().isEmpty()) {
            throw new BusinessException("URL不能为空");
        }

        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            throw new BusinessException("URL必须以http://或https://开头");
        }

        // 防止 SSRF 攻击:禁止访问内网 IP
        try {
            URL urlObj = new URL(url);
            String host = urlObj.getHost();

            // 禁止访问 localhost 和 127.0.0.1
            if (host.equals("localhost") ||
                    host.equals("127.0.0.1") ||
                    host.equals("0.0.0.0") ||
                    host.equals("::1")) {
                throw new BusinessException("禁止访问本地地址");
            }

            // 禁止访问内网 IP 段
            if (isPrivateIp(host)) {
                throw new BusinessException("禁止访问内网地址");
            }

        } catch (MalformedURLException e) {
            throw new BusinessException("URL格式不正确: " + e.getMessage());
        }
    }

    /**
     * 检查是否为私有 IP 地址
     */
    private boolean isPrivateIp(String host) {
        if (host.startsWith("192.168.")) return true;
        if (host.startsWith("10.")) return true;

        if (host.startsWith("172.")) {
            try {
                String[] parts = host.split("\\.");
                if (parts.length >= 2) {
                    int secondOctet = Integer.parseInt(parts[1]);
                    if (secondOctet >= 16 && secondOctet <= 31) {
                        return true;
                    }
                }
            } catch (NumberFormatException e) {
                // 忽略解析错误
            }
        }

        return false;
    }
}
